package com.conwax.gmap;

import java.util.HashMap;
import java.util.Map;

import org.apache.wicket.Session;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.AbstractAjaxBehavior;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.MarkupStream;
import org.apache.wicket.markup.html.WebComponent;
import org.apache.wicket.util.string.JavascriptUtils;
import org.apache.wicket.util.value.IValueMap;

import com.conwax.gmap.event.ClickHandler;
import com.conwax.gmap.event.GEventHandler;
import com.conwax.gmap.event.GEventListener;
import com.conwax.gmap.event.GEventSource;

public class GEventHook extends WebComponent
{

	private static final long serialVersionUID = 1L;
	private final String target = "window";
	private final String event = "\"domready\"";
	private final int id;
	private final AbstractAjaxBehavior behavior;
	private Map<Integer, Object> listenerMap = new HashMap<Integer, Object>();

	public GEventHook(String id)
	{
		super(id);
		this.id = Session.get().nextSequenceValue();
		this.setOutputMarkupId(true);
		this.add(behavior = new AbstractAjaxBehavior(){

			private static final long serialVersionUID = 1L;

			public void onRequest()
			{
				// TODO Auto-generated method stub
				
			}
			
		});
	}

	/**
	 * @see org.apache.wicket.Component#onComponentTag(org.apache.wicket.markup.ComponentTag)
	 */
	@Override
	protected void onComponentTag(ComponentTag tag)
	{
		// Must be attached to a script tag
		checkComponentTag(tag, "script");
		IValueMap attributes = tag.getAttributes();
		attributes.put("type", "text/javascript");
	}

	/**
	 * @see org.apache.wicket.Component#onComponentTagBody(org.apache.wicket.markup.MarkupStream,
	 *      org.apache.wicket.markup.ComponentTag)
	 */
	@Override
	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
	{
		replaceComponentTagBody(markupStream, openTag, JavascriptUtils.SCRIPT_CONTENT_PREFIX
				+ getJSInit() + JavascriptUtils.SCRIPT_CONTENT_SUFFIX);
	}

	public String getJSInit()
	{
		String jsInit = "Wicket.Event.add(" + target + ", " + event + ", function(event) { "
				+ "WicketConGoogle.EventHook(\"" + id + "\", \"" + behavior.getCallbackUrl() + "\");});";
		return jsInit;
	}

	@Override
	protected void onRemove()
	{
		if (AjaxRequestTarget.get() != null)
		{
			AjaxRequestTarget.get().appendJavascript(
					"remove the JavaScript objects that belong to me.");
		}
		super.onRemove();
	}

	public GEventListener addListener(Map2NG map, ClickHandler clickHandler)
	{
		int listenerId = Session.get().nextSequenceValue();
		this.listenerMap.put(listenerId, new MapHandlerTuple(map, clickHandler));
		return new GEventListener(listenerId);
	}
	
	private class MapHandlerTuple {
		public final GEventSource gEventSource;
		public final GEventHandler gEventListener;

		public MapHandlerTuple(GEventSource source,
				GEventHandler listener) {
			this.gEventSource = source;
			this.gEventListener = listener;
		}
	}
}
